package com.ellfors.common.http.utils

import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Protocol
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.X509TrustManager
import kotlin.jvm.Throws

/**
 * NetBuilder
 * 2021-05-13 13:54
 */
class NetBuilder {

    private val okHttpBuilder by lazy {
        OkHttpClient.Builder()
    }

    fun setConnectTimeout(outTime: Int): NetBuilder {
        okHttpBuilder.connectTimeout(outTime.toLong(), TimeUnit.SECONDS)
        return this
    }

    fun setReadTimeout(outTime: Int): NetBuilder {
        okHttpBuilder.readTimeout(outTime.toLong(), TimeUnit.SECONDS)
        return this
    }

    fun setWriteTimeout(outTime: Int): NetBuilder {
        okHttpBuilder.writeTimeout(outTime.toLong(), TimeUnit.SECONDS)
        return this
    }

    fun setSslFactory(): NetBuilder {
        try {
            val trustManager: X509TrustManager = object : X509TrustManager {
                @Throws(CertificateException::class)
                override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {

                }

                @Throws(CertificateException::class)
                override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {

                }

                override fun getAcceptedIssuers(): Array<X509Certificate?> {
                    return arrayOfNulls(0)
                }
            }

            // Install the all-trusting trust manager
            val sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, arrayOf(trustManager), SecureRandom())

            // Create an ssl socket factory with our all-trusting manager
            val sslSocketFactory = sslContext.socketFactory
            okHttpBuilder.apply {
                sslSocketFactory(sslSocketFactory, trustManager)
                protocols(listOf(Protocol.HTTP_1_1))
                hostnameVerifier { _, _ -> true }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return this
    }

    fun setRetryOnConnectionFailure(retry: Boolean): NetBuilder {
        okHttpBuilder.retryOnConnectionFailure(retry)
        return this
    }

    fun addInterceptor(interceptor: Interceptor?): NetBuilder {
        interceptor?.let {
            okHttpBuilder.addInterceptor(it)
        }
        return this
    }

    fun addNetworkInterceptor(interceptor: Interceptor?): NetBuilder {
        interceptor?.let {
            okHttpBuilder.addNetworkInterceptor(it)
        }
        return this
    }

    fun addCache(cache: Cache?): NetBuilder? {
        okHttpBuilder.cache(cache)
        return this
    }

    fun getClient(): OkHttpClient {
        return okHttpBuilder.build()
    }

    fun build(url: String): Retrofit {
        return Retrofit.Builder()
            .client(okHttpBuilder.build())
            .addConverterFactory(GsonConverterFactory.create())
//            .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
            .baseUrl(url)
            .build()
    }
}